﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GALibrary.Entity;
using System.IO;
using GALibrary.Scheduling;
using GALibrary.FormTemplate;

namespace Comp307_GroupAssignment
{
    public partial class Comp307_GP : BaseForm
    {
        private int lastTextboxPosition;
        private TextBox lastTextbox;
        List<TaskSchedulerGA> taskList = new List<TaskSchedulerGA>();
        public Comp307_GP()
        {
            InitializeComponent();
            lastTextboxPosition = panel1.Location.Y;
            this.AllowDrop = true;
            this.DragEnter += this.fileList_DataGridView_DragDrop;
           
            

           // this.fileList_DataGridView.AutoSize = true;
            this.fileList_DataGridView.AllowDrop = true;


          

          /*  Label l = new Label
            {
                Text = "0     5",
                Location = new Point(0, lastTextboxPosition),
                Size = new Size(40, 32),
                BackColor = getRandomColor(),
            };
             panel1.Controls.Add(l);
            lastTextboxPosition += 15;
           */

        }

        private void fileList_DataGridView_DragDrop(object sender, DragEventArgs e)
        {
            var files = e.Data.GetData(DataFormats.FileDrop) as string[];
            //this.fileCheckedListBox.Items.Clear();
            this.fileList_DataGridView.Refresh();
            taskList = new List<TaskSchedulerGA>();
            foreach (var file in files)
            {
                string tempFileName = Path.GetFileName(file);
                using (StreamReader sr = new StreamReader(file))
                {
                    String textSource = sr.ReadToEnd();
                    var lines = textSource.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
                    foreach (var line in lines)
                    {
                        if (!string.IsNullOrEmpty(line.Trim()))
                        {
                            TaskSchedulerGA tempData = new TaskSchedulerGA();
                            int taskID, startingTime, duration, priority;
                            var warData = line.Split(',');
                            if (warData.Count() == 4 && int.TryParse(warData[0], out taskID)
                                && int.TryParse(warData[1], out startingTime)
                                && int.TryParse(warData[2], out duration)
                                && int.TryParse(warData[3], out priority))
                            {

                                taskList.Add(new TaskSchedulerGA(taskID, startingTime, duration, priority, tempFileName));

                            }
                            else
                            {
                                this.richTextBoxInfo.Text += "Error data format: " + line + "\n";
                            }
                        }
                    }
                }
               // this.fileCheckedListBox.Items.Add(tempFileName);
            }
           
            this.fileList_DataGridView.DataSource = taskList;
           
        }


        private void fileList_DataGridView_DragOver(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.All;
            Console.Out.Write("DragOver");
        }

        private void start_Button_Click(object sender, EventArgs e)
        {
            // step 0
            // new current_Level_Scheduler(next_level_scheduler)
            FCFS bottonLevel = new FCFS(null);

            //ShortestJobFirst ps = new ShortestJobFirst(null);

            ShortestRemainingTime secLevel = new ShortestRemainingTime(bottonLevel);

            PriorityScheduler topLevel = new PriorityScheduler(secLevel);
           // PriorityScheduler ps2 = new PriorityScheduler(null);
            
           // ShortestRemainingTime srt = new ShortestRemainingTime(fcfs);
            
           // FCFS fcfs2 = new FCFS(null);
            
            //RoundRobin RR = new RoundRobin(3);
            int timer = 0;
            int position = 0;
           // taskList = taskList.OrderBy(p => p.StartingTime).ThenBy(p => p.Priority).Select(p => p).ToList();
            List<TaskSchedulerGA> tempAvailableTask ;
            List<TaskSchedulerGA> recordTask = new List<TaskSchedulerGA>();
            while ((tempAvailableTask= taskList.Where(p=>p.ExecutedDuration != p.Duration).Select(p=>p).ToList()).Count() != 0)
            {
                var tempOnTimeTasks = taskList.Where(p => p.StartingTime == timer).Select(p => p).ToList();
                // add task support arrive at same time
                foreach (var item in tempOnTimeTasks)
                {
                   // ps.AddTask(item);
                    //fcfs.AddTask(item);
                    //step 1
                    topLevel.AddTask(item);
                    //position++;
                }
                //step 2
                var tempTask = topLevel.StartAtTime(timer++);
                if (tempTask != null)
                {
                    if (!this.taskColor.ContainsKey(tempTask.TaskId))
                    {   
                        Color color = this.getRandomColor();
                        this.taskColor.Add(tempTask.TaskId, color);
                    }
                    if (recordTask.Count() > 0 && recordTask.LastOrDefault().TaskId == tempTask.TaskId)
                    {
                        recordTask.LastOrDefault().Duration++;
                    }
                    else
                    {
                        recordTask.Add(new TaskSchedulerGA(tempTask.TaskId, timer - 1, 1, 0, tempTask.Filename));
                    }

                    foreach (var item in taskList.Where(p => p.TaskId == tempTask.TaskId))
                    {
                        item.TurnaroundTime = tempTask.TurnaroundTime;
                        item.WaitingTime = tempTask.WaitingTime;
                    }
                }
            }
            var totalWaitingTime = this.taskList.Select(p => p.WaitingTime).Sum(p => p);
            var totalRunningTime = this.taskList.Select(p => p.TurnaroundTime).Sum(p => p);
            var totalTask = this.taskList.Count();
            richTextBoxInfo.Text += "Average Tuenaround Time: " + (float)totalRunningTime/totalTask + "\n";
            richTextBoxInfo.Text += "Average Waiting Time: " + (float)totalWaitingTime / totalTask + "\n";
            ChartForm cf = new ChartForm(taskColor,recordTask);
            
            
            
            cf.Show();
            this.fileList_DataGridView.Refresh();
         /*   for (int i = 0; i < taskList.Count(); i++)
            {
                if (taskList[i].StartingTime == timer)
                {
                    ps.AddTask(taskList[i]);
                    i++;
                }
                ps.StartAtTime(timer++);
                i--;
            }
          */
/*            foreach (var task in taskList)
            {
                if (task.StartingTime == timer)
                {
                    RR.AddTask(task);
                }
                RR.StartAtTime(timer++);
            }*/
        }
    }
}
